
import torch
import numpy as np
from typing import List, Tuple, Union

def to_flattened_numpy(tensor)->Tuple[np.ndarray, Union[torch.Size, Tuple]]:
    """Flatten a torch tensor and convert it to numpy."""
    tensor_shape = tensor.shape
    flattend_numpy = tensor.detach().cpu().numpy().reshape((-1,))
    return flattend_numpy, tensor_shape


def from_flattened_numpy(flattend_numpy:np.ndarray, tensor_shape:Union[torch.Size, Tuple])->torch.Tensor:
    """Form a torch tensor with the given `shape` from a flattened numpy array `x`."""
    return torch.from_numpy(flattend_numpy).reshape(tensor_shape)